home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Very Best of Atari Inside
/
The Very Best of Atari Inside 1.iso
/
mint
/
mntlib25
/
bblink.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-04
|
4KB
|
136 lines
/*
* block profile support for gcc.
* ++jrb bammi@cadence.com
*/
#include <compiler.h>
#include <stdio.h>
#include <stdlib.h>
/* block count struct produced by gcc -tcov */
typedef struct _bb_count {
long initialized; /* has __bb_init_func been called */
char *filename; /* filename for .d file */
long *block_counts; /* address of block count table */
long ncount; /* sizeof block count table */
/* ie: # of basic blocks in file */
struct _bb_count *next; /* in memory link to next struct */
char ***addr_table; /* addr of basic block address table */
/* size of addr_table == ncount+1 */
} BB_COUNT;
void __bb_init_func __PROTO((BB_COUNT *));
static void exit_func __PROTO((void)); /* installed to be called at exit */
static void save_info __PROTO((BB_COUNT *));
/* vars */
static BB_COUNT *hdr = NULL; /* list of all bb_count for which
__bb_init_func has been called */
static char first_call = 1; /* flags first call to __bb_init_func */
static char at_exit_failed = 0; /* flag to indicate that atexit() failed */
/*
* called by gcc -tcov generated code on first entry into a function
*/
void __bb_init_func(bb_count)
BB_COUNT *bb_count;
{
if(at_exit_failed)
return;
if(first_call)
{
if(atexit(exit_func))
{
fprintf(stderr, "Failed to install exit function. No block \
profile information will be saved\n");
at_exit_failed = 1;
return;
}
first_call = 0;
}
if(bb_count->initialized == 0)
{ /* link into list of bb_counts */
bb_count->next = hdr;
hdr = bb_count;
bb_count->initialized = 1;
}
}
/*
* called on normal exit
* write out block profile files for each bb_count struct in list.
*/
static void exit_func()
{
BB_COUNT *p;
for(p = hdr; p; p = p->next)
save_info(p);
}
typedef struct {
long lineno; /* start of block */
long count; /* # executions (cumulative over runs) */
} DINFO;
/*
* given a bb_count struct, save info into .d file
*/
static void save_info(p)
BB_COUNT *p;
{
FILE *fp;
long i, *bcounts;
DINFO *dinfo = malloc(p->ncount * sizeof(DINFO));
if(!dinfo)
{
fprintf(stderr, "No memory to process %s. Skipped\n", p->filename);
return;
}
if((fp = fopen(p->filename, "r")) == NULL)
{
fprintf(stderr,"Failed to open %s for read. Skipped\n", p->filename);
free(dinfo);
return;
}
/* read .d file & accumulate counts */
for(i = 0, bcounts = p->block_counts;
fscanf(fp, "%ld%ld", &dinfo[i].lineno, &dinfo[i].count) == 2; i++)
{
if(i >= p->ncount)
{
fprintf(stderr, "Block counts in %s exceed expected %ld, rest skipped\n",
p->filename, p->ncount);
break;
}
dinfo[i].count += bcounts[i];
}
fclose(fp);
if(i < p->ncount)
{
fprintf(stderr, "Warning Block counts in %s less than expected %ld\n",
p->filename, p->ncount);
}
if((fp = fopen(p->filename, "w")) == NULL)
{
fprintf(stderr,"Failed to open %s for write. Skipped\n", p->filename);
free(dinfo);
return;
}
for(i = 0; i < p->ncount; i++)
{
if(fprintf(fp, "\t%ld\t%ld\n", dinfo[i].lineno, dinfo[i].count) == EOF)
{
fprintf(stderr,"Write Failed to %s\n", p->filename);
free(dinfo);
fclose(fp);
return;
}
}
fclose(fp);
free(dinfo);
}